/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package leastsquaresapproximation;
import java.awt.*; 
import java.awt.geom.*; 
import java.util.ArrayList;
import javax.swing.*; 
  
public class Plotter extends JPanel { 
    public ArrayList<Double> polynom;
    public ArrayList<Double> xPoints;
    public ArrayList<Double> yPoints;
    public ArrayList<ArrayList<Double>> polynoms;
    final int PAD = 20; 
  
    public Plotter(ArrayList<Double> x, ArrayList<Double> y, ArrayList<ArrayList<Double>> polynoms){
	xPoints = x;
	yPoints = y;
	this.polynoms = polynoms;
    }
    
    @Override
    protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        Graphics2D g2 = (Graphics2D)g; 
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                            RenderingHints.VALUE_ANTIALIAS_ON); 
        int w = getWidth(); 
        int h = getHeight(); 
        // Draw ordinate. 
        g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD)); 
        // Draw abcissa. 
        g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
	
	
        double xInc = (double)(w - 2*PAD)/(getMaxX()*1.1); 
        double scale = (double)(h - 2*PAD)/(getMaxY()*1.1); 	

/*        // Draw lines between points. 
        g2.setPaint(Color.green.darker()); 
        for(int i = 0; i < yPoints.length-1; i++) { 
            double x1 = PAD + (i+1)*xInc; 
            double y1 = h - PAD - scale*yPoints[i]; 
            double x2 = PAD + (i+2)*xInc; 
            double y2 = h - PAD - scale*yPoints[i+1]; 
            g2.draw(new Line2D.Double(x1, y1, x2, y2)); 
        } 
//*/	
	
        // Mark data points. 
        g2.setPaint(Color.red); 
        for(int i = 0; i < yPoints.size(); i++) { 
            double x = PAD + xPoints.get(i) *xInc; 
            double y = h - PAD - scale*yPoints.get(i); 
            g2.fill(new Ellipse2D.Double(x-3, y-3, 6, 6)); 
        } 
	
	// Draw polynomials
	for(int i = 0; i < polynoms.size(); i++){
	    // Draw polynomials
	    g2.setPaint(nextCollor(i));
	    double xIter = 0.0;
	    double xDelta = 0.0078125;
	    while(xIter < getMaxX()+1){
		double x1 = PAD + (xIter)*xInc;
		double y1 = h - PAD - scale*getFunction(xIter, i);
		double x2 = PAD + (xIter + xDelta)*xInc;
		double y2 = h - PAD - scale*getFunction(xIter + xDelta, i); 
		g2.draw(new Line2D.Double(x1, y1, x2, y2)); 
		xIter += xDelta;
	    }
	}
    } 
  
    private Color nextCollor(int i){
	i = i%6;
	Color c = Color.BLACK;
	switch(i){
	    case 0: c = Color.GREEN;	break;
	    case 1: c = Color.BLUE;	break;
	    case 2: c = Color.CYAN;	break;
	    case 3: c = Color.ORANGE;	break;
	    case 4: c = Color.YELLOW;	break;
	    case 5: c = Color.MAGENTA;	break;
	}
	return c;
    }
    
    private double getMaxY() { 
        double max = Double.MIN_VALUE;
        for(int i = 0; i < yPoints.size(); i++) { 
            if(yPoints.get(i) > max) 
                max = yPoints.get(i); 
        } 
        return max; 
    } 
    private double getMaxX() { 
        double max = Double.MIN_VALUE;
        for(int i = 0; i < xPoints.size(); i++) { 
            if(xPoints.get(i) > max) 
                max = xPoints.get(i); 
        } 
        return max; 
    } 
    
    public Double getFunction(double x, int polynomNumber){
	double fx = 0.0;
	for(int i = 0; i<polynoms.get(polynomNumber).size(); i++){
	    fx += polynoms.get(polynomNumber).get(i)*Math.pow(x, polynoms.get(polynomNumber).size()-i-1);
	}
	return fx;
    }
}
